package main  

import (
	"context"
	"fmt"
	"time"
	"go.etcd.io/etcd/clientv3"
)
// etcd 的docker 集群安装可以参考腾讯文档即可
// etcd client put/get demo
// use etcd /clientv3

func etcdSet(cli *clientv3.Client){
 // put
 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
 _, err := cli.Put(ctx, "小猪","真帅")
 cancel()
 if err !=nil{
	 fmt.Printf("put to etcd failed , err :%v\n", err)
	 return
 }
}
func etcdGet(cli *clientv3.Client){
	ctx,cancel := context.WithTimeout(context.Background(), time.Second)
	resp, err := cli.Get(ctx, "小猪")
	cancel()
	if err!=nil{
		fmt.Printf("get from etcd failed , err:%v\n",err)
		return
	}
	for _, ev := range resp.Kvs {
		fmt.Printf("%s, %s \n", ev.Key, ev.Value)
	}
}
func etcdWatch(cli *clientv3.Client){
	// watch key:小猪 change
	rch := cli.Watch(context.Background(), "小猪") // <-chan WatchResponse
	for wresp := range rch{
		for _, ev:=range wresp.Events{
			fmt.Printf("Type : %s Key :%s Value : %s\n",ev.Type,ev.Kv.Key,ev.Kv.Value)
		}
	}
}

func etcdLease(cli *clientv3.Client){

	// 创建一个5秒的租约
	resp, err := cli.Grant(context.TODO(), 5)
	if err != nil {
		fmt.Println(err)
	}

	// 5秒钟之后, /nazha/ 这个key就会被移除
	_, err = cli.Put(context.TODO(), "/nazha/", "dsb", clientv3.WithLease(resp.ID))
	if err != nil {
		fmt.Println(err)
	}
}
func etcdKeepAlive(cli *clientv3.Client){
	resp, err := cli.Grant(context.TODO(), 5)
	if err != nil {
		fmt.Println(err)
	}

	_, err = cli.Put(context.TODO(), "/nazha/", "dsb", clientv3.WithLease(resp.ID))
	if err != nil {
		fmt.Println(err)
	}

	// the key 'foo' will be kept forever
	ch, kaerr := cli.KeepAlive(context.TODO(), resp.ID)
	if kaerr != nil {
		fmt.Println(kaerr)
	}
	for {
		ka := <-ch
		fmt.Println("ttl:", ka.TTL)
	}
}

func main(){
  cli, err := clientv3.New(clientv3.Config{
	  Endpoints:[]string{"127.0.0.1:12379","127.0.0.1:22379","127.0.0.1:32379"},
	  DialTimeout : 5 * time.Second,
  })
  if err !=nil{
	  fmt.Printf("connect to etcd failed, err: %v\n", err)
	  return
  }
  fmt.Println("connect to etcd success")
  defer cli.Close()

  etcdSet(cli)
  // get
  etcdGet(cli)
  // watch
//   etcdWatch(cli)
  // lease租约
  etcdLease(cli)
  // keepAlive
  etcdKeepAlive(cli)
}